#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@File    :   wechat_handle.py
@Time    :   2025/06/08 15:05:22
@Author  :   Rico Chen
@Mail    :   55059@qq.com
@Version :   1.0
@Desc    :   用fastapi处理微信,hook,消息, 认证等
"""
from fastapi import FastAPI, Request, Response
from fastapi.responses import HTMLResponse, RedirectResponse, PlainTextResponse
from wechatpy import parse_message, create_reply
from wechatpy.utils import check_signature
from wechatpy.oauth import WeChatOAuth
from wechatpy.client import WeChatClient
from wechatpy.exceptions import InvalidSignatureException
import os
from nicegui import app
from typing import Optional
import functools
import uuid
from fastapi import FastAPI, Request, Response, Depends, HTTPException
from fastapi.responses import RedirectResponse, JSONResponse
import uvicorn

app = FastAPI()
# 微信配置
WX_APPID = "wxd6c52d789ba647a3"
WX_APPSECRET = "09711e97e05c45c28eb6f1acfad3028f"
WX_SIGN_TOKEN = "fly2me"
WX_AES_KEY = "ypeT82YKMt4V7OAM39riG9v7lJu3CpN72yiIp7EnQNW" or None
wechat_client = WeChatClient(WX_APPID, WX_APPSECRET)


@app.get("/wxhook")
# @app.api_route("/wxhook", methods=["GET", "POST"])post 是用来回复信息的。
async def wechat_hook(signature: str, timestamp: str, nonce: str, echostr: str):
    """微信服务器的验证配置请求"""
    try:
        check_signature(WX_SIGN_TOKEN, signature, timestamp, nonce)
        # return HTMLResponse(content=echostr)
        print(f"echostr: {echostr}")
        return int(echostr)  # 坑一：要返回int型的echostr
    except InvalidSignatureException:
        return "Invalid signature"


@app.post("/wxhook")
async def wechat_message(request: Request):
    """处理微信消息"""
    body = await request.body()
    msg = parse_message(body)

    # 处理文本消息
    if msg.type == "text" and msg.content == "我在那":
        # 检查用户是否发送了位置信息
        if hasattr(msg, "location_x") and hasattr(msg, "location_y"):
            # 用户已发送位置信息
            latitude = msg.location_x
            longitude = msg.location_y
            reply_text = f"您当前的位置是：\n经度：{longitude}\n纬度：{latitude}"
        else:
            # 请求用户发送位置
            reply_text = "请点击公众号底部的'+'号，然后选择'位置'，发送您的位置给我"
        # 创建回复
        reply = create_reply(reply_text, msg)
    elif msg.type == "location":
        # 用户发送了位置信息
        latitude = msg.location_x
        longitude = msg.location_y
        reply_text = f"您当前的位置是：\n经度：{longitude}\n纬度：{latitude}"
        reply = create_reply(reply_text, msg)
    else:
        # 其他消息回复默认内容
        reply = create_reply("发送'我在那'可以查询您的位置", msg)
    return PlainTextResponse(reply.render())


# http://www.dgpms.cn/wxsend?openid=oiszc0fnrDeVfohzzCsqT_89pPVs&message=%E6%B5%8B%E8%AF%95%E6%B6%88%E6%81%AF12354
@app.get("/wxsend")
async def send_message(openid: str, message: str):
    """发送客服消息"""
    try:
        result = wechat_client.message.send_text(openid, message)
        return {"success": True, "result": result}
    except Exception as e:
        return {"error": str(e)}, 400


# 微信认证文件,建议通过nginx配置
@app.get("/MP_verify_XrLQ2lIqovTx3yQr.txt")
def WechatAuthFile():
    return HTMLResponse(content="XrLQ2lIqovTx3yQr")


@app.get("/wxcreatemenu")
def create_menu():
    """创建自定义菜单"""
    menu_data = {
        "button": [
            {"type": "click", "name": "经纬度", "key": "V1001_TODAY_MUSIC"},
            {"type": "click", "name": "环评", "key": "V1001_TODAY_SINGER"},
            {
                "name": "菜单",
                "sub_button": [
                    {"type": "view", "name": "基站", "url": "http://www.soso.com/"},
                    {"type": "view", "name": "门禁", "url": "http://v.qq.com/"},
                    {"type": "click", "name": "赞一下我们", "key": "V1001_GOOD"},
                ],
            },
        ]
    }
    return wechat_client.menu.create(menu_data)


@app.get("/wxgetaccesstoken")
def get_access_token():
    """获取access_token"""
    return wechat_client.fetch_access_token()


@app.get("/hello")
async def hello():
    print("Hello, WeChat!")
    return {"message": "Hello, WeChat!"}
    # return Response(status_code=400, content="Invalid message")


@app.get("/wxauth")
async def wechat_auth(code: str = None, state: str = None, redirect_uri: str = None):
    """微信网页授权"""
    if not code:
        # 第一步：如果没有code,即不是回调的callback,重定向到微信授权页面
        oauth = WeChatOAuth(
            WX_APPID,
            WX_APPSECRET,
            redirect_uri=redirect_uri or f"http://www.dgpms.cn/wxauth",
            scope="snsapi_userinfo",
            state=state,
        )
        return RedirectResponse(url=oauth.authorize_url)

    # 第二步：如果是callback,取code,获取用户信息
    try:
        oauth = WeChatOAuth(
            WX_APPID,
            WX_APPSECRET,
            redirect_uri=redirect_uri or f"http://www.dgpms.cn/wxauth",
        )
        oauth.fetch_access_token(code)
        user_info = oauth.get_user_info()
        print(f"User info: {user_info}")
        # 保存用户信息到数据库
        # db = SessionLocal()
        # user = db.query(User).filter(User.openid == user_info["openid"]).first()
        # if not user:
        #     user = User(
        #         openid=user_info["openid"],
        #         nickname=user_info["nickname"],
        #         avatar=user_info["headimgurl"],
        #     )
        #     db.add(user)
        # else:
        #     user.nickname = user_info["nickname"]
        #     user.avatar = user_info["headimgurl"]
        # db.commit()

        # 返回用户信息或重定向
        return {
            "openid": user_info["openid"],
            "nickname": user_info["nickname"],
            "avatar": user_info["headimgurl"],
        }

    except Exception as e:
        return {"error": str(e)}, 400


if __name__ == "__main__":
    uvicorn.run(app="wechat_handle:app", host="0.0.0.0", port=80, reload=True)
